---
image: https://assets.vercel.com/image/upload/v1670542323/swr/v2.png
description: "Anunciando SWR 2.0: Novas APIs de mutação e melhorias nas capacidades de UI otimista, novas ferramentas de desenvolvedor, melhor suporte para renderização concorrente e muito mais."
date: December 9th, 2022
---

import { Callout } from 'nextra-theme-docs'
import { Bleed } from 'nextra-theme-docs'

import Authors, { Author } from 'components/authors'
import Video from 'components/video'

# Anunciando SWR 2.0 [#announcing-swr-20]

<Authors date="December 9th, 2022">
  <Author name="Shu Ding" link="https://twitter.com/shuding_" />
  <Author name="Jiachi Liu" link="https://twitter.com/huozhi" />
  <Author name="Toru Kobayashi" link="https://twitter.com/koba04" />
  <Author name="Yixuan Xu" link="https://twitter.com/yixuanxu94" />
</Authors>


Nós estamos muito felizes em anunciar o lançamento do SWR 2.0, a popular biblioteca de busca de dados para React que permite que componentes busquem, armazenem em cache, alterem dados e que mantém a UI atualizada com as alterações nesses dados ao longo do tempo. 

Essa nova versão chega carregada com melhorias e novas funcionalidades, como novas APIs de mutação, melhorias nas capacidades de UI otimista, novas ferramentas de desenvolvedor e melhor suporte para renderização concorrente. Gostaríamos de agradecer a todos os contribuidores e mantenedores que tornaram esse lançamento possível.

## Mutação e UI Otimista [#mutation-and-optimistic-ui]

### useSWRMutation [#useswrmutation]

Mutação é uma parte importante do processo de data fetching. Elas permitem que você faça alterações em seus dados tanto localmente quanto remotamente. Nossa API existente `mutate` permite que você revalide e altere recursos manualmente. No SWR 2.0, o novo hook `useSWRMutation` torna ainda mais simples alterar dados remotamente usando uma API declarativa. Você pode configurar uma mutação usando o hook e em seguida, ativá-la mais tarde:

```jsx {11,16}
import useSWRMutation from 'swr/mutation'

async function sendRequest(url, { arg }) {
  return fetch(url, {
    method: 'POST',
    body: JSON.stringify(arg)
  })
}

function App() {
  const { trigger, isMutating } = useSWRMutation('/api/user', sendRequest)

  return (
    <button
      disabled={isMutating}
      onClick={() => trigger({ username: 'johndoe' })}
    >{
      isMutating ? 'Criando...' : 'Criar usuário'
    }</button>
  )
}
```

O exemplo acima define uma mutação `sendRequest` que afeta o recurso `'/api/user'`. Ao contrário de `useSWR`, `useSWRMutation` não iniciará imediatamente a requisição ao renderizar. Em vez disso, ele retorna uma função `trigger` que pode ser chamada posteriormente para iniciar manualmente a mutação.

A função `sendRequest` será chamada quando o botão for clicado, junto com o argumento extra `{ username: 'johndoe' }`. O valor de `isMutating` será definido como `true` até que a mutação tenha terminado.

Adicionalmente, esse novo hook resolve outros problemas que você pode ter com mutações:

- Atualiza a UI otimisticamente enquanto os dados estão sendo alterados
- Reverte automaticamente quando a mutação falha
- Evita qualquer potencial conflito entre `useSWR` e outras mutações do mesmo recurso
- Preenche o cache do `useSWR` após a mutação ser concluída
- ...

Você pode achar referências de API e exemplos mais detalhados lendo a [documentação](/docs/mutation#useswrmutation) ou rolando pelas próximas seções.

### UI Otimista [#optimistic-ui]

UI Otimista é um exelente modelo para criar sites que sejam rápidos e responsivos; no entanto, pode ser difícil implementá-lo corretamente. O SWR 2.0 adicionou algumas novas opções poderosas para facilitar isso.

Vamos supor que tenhamos uma API que adiciona um novo item à lista de tarefas e o envia ao servidor:

```jsx
await addNewTodo('Novo Item')
```

Na nossa UI, usamos um hook `useSWR` para exibir a lista de tarefas, com um botão “Adicionar novo item” que dispara essa requisição e pede ao SWR para rebuscar os dados via `mutate()`:

```jsx {7,8}
const { mutate, data } = useSWR('/api/todos')

return <>
  <ul>{/* Exibir dados */}</ul>

  <button onClick={async () => {
    await addNewTodo('Novo Item')
    mutate()
  }}>
    Adicionar novo item
  </button>
</>
```

Entretanto, a requisição `await addNewTodo(...)` pode ser muito lenta. Quando estiver em andamento, os usuários ainda verão a lista antiga, mesmo que já saibamos como será a nova lista. Com a nova opção `optimisticData`, podemos mostrar a nova lista otimisticamente, antes que o servidor responda:

```jsx {8}
const { mutate, data } = useSWR('/api/todos')

return <>
  <ul>{/* Exibir dados */}</ul>

  <button onClick={() => {
    mutate(addNewTodo('Novo Item'), {
      optimisticData: [...data, 'Novo Item'],
    })
  }}>
    Adicionar novo item
  </button>
</>
```

O SWR irá imediatamente atualizar `data` com o valor de `optimisticData` e, em seguida, enviar a requisição ao servidor. Assim que a requisição terminar, o SWR revalidará o recurso para garantir que seja o mais recente.

Assim como muitas APIs, se a requisição `addNewTodo(...)` retornar os dados mais recentes do servidor, também podemos exibir diretamente esse resultado (em vez de iniciar uma nova revalidação)! Existe a nova opção `populateCache` para dizer ao SWR para atualizar os dados locais com a resposta da mutação:

```jsx {9}
const { mutate, data } = useSWR('/api/todos')

return <>
  <ul>{/* Exibir dados */}</ul>

  <button onClick={() => {
    mutate(addNewTodo('Novo Item'), {
      optimisticData: [...data, 'Novo Item'],
      populateCache: true,
    })
  }}>
    Adicionar novo item
  </button>
</>
```

Ao mesmo tempo, não precisamos de outra revalidação depois, pois os dados da resposta são da fonte da verdade, podemos desativá-la com a opção `revalidate`:

```jsx {10}
const { mutate, data } = useSWR('/api/todos')

return <>
  <ul>{/* Exibir dados */}</ul>

  <button onClick={() => {
    mutate(addNewTodo('Novo Item'), {
      optimisticData: [...data, 'Novo Item'],
      populateCache: true,
      revalidate: false,
    })
  }}>
    Adicionar novo item
  </button>
</>
```

Por último, se `addNewTodo(...)` falhar com uma exceção, podemos reverter os dados otimistas (`[...data, 'Novo Item']`) que acabamos de definir, definindo `rollbackOnError` como `true` (que também é a opção padrão). Quando isso acontece, o SWR reverterá `data` para o valor anterior.

```jsx {11}
const { mutate, data } = useSWR('/api/todos')

return <>
  <ul>{/* Exibir dados */}</ul>

  <button onClick={() => {
    mutate(addNewTodo('Novo Item'), {
      optimisticData: [...data, 'Novo Item'],
      populateCache: true,
      revalidate: false,
      rollbackOnError: true,
    })
  }}>
    Adicionar novo item
  </button>
</>
```

Todas essas APIs são suportadas no novo hook `useSWRMutation` também. Para saber mais sobre elas, você pode conferir nossa [documentação](/docs/mutation#atualizações-otimistas). Aqui está uma demo mostrando esse comportamento:

<Video
  src="/video/optimistic-ui.mp4"
  caption="UI Otimista com reversão automática de erros"
  ratio={223/584}
/>

### Modificando Múltiplas Chaves [#mutate-multiple-keys]

A API global `mutate` agora aceita uma função de filtro, onde você pode mutar ou revalidar chaves específicas. Isso será útil para casos de uso como invalidar todos os dados em cache. Para saber mais, você pode ler [Modificando Múltiplas Chaves](/docs/mutation#modificando-múltiplos-items) na documentação.

```jsx
import { mutate } from 'swr'
// Ou do hook se você tiver customizado seu provedor de cache:
// { mutate } = useSWRConfig()

// Modificar um único recurso
mutate(key)

// Modificar múltiplos recursos e limpar o cache (definir como undefined)
mutate(
  key => typeof key === 'string' && key.startsWith('/api/item?id='),
  undefined,
  { revalidate: false }
)
```

## SWR DevTools [#swr-devtools]

O [SWRDevTools](https://swr-devtools.vercel.app) é uma extensão do navegador que ajuda você a depurar o cache do SWR e os resultados das requisições. Confira nossa [seção de DevTools](/docs/advanced/devtools) para saber como usar o devtools em sua aplicação.

![](/img/devtools/cache-view.jpg)

## Pré-carregando Dados [#preloading-data]

Precarregar dados pode melhorar a experiência do usuário tremendamente. Se você souber que o recurso será usado mais tarde na aplicação, pode usar a nova API `preload` para começar a carregá-lo mais cedo:

```jsx {6}
import useSWR, { preload } from 'swr'

const fetcher = (url) => fetch(url).then((res) => res.json())

// Você pode chamar a função preload em qualquer lugar
preload('/api/user', fetcher)

function Profile() {
  // O componente que realmente usa os dados:
  const { data, error } = useSWR('/api/user', fetcher)
  // ...
}

export function Page () {
  return <Profile/>
}
```

Nesse exemplo, a `preload` API é chamada no escopo global. Isso significa que começamos a pré-carregar o recurso antes mesmo que o React comece a renderizar qualquer coisa.
E quando o componente `Profile` estiver sendo renderizado, os dados provavelmente já estarão disponíveis. Se ainda estiver em andamento, o hook `useSWR` reutilizará essa solicitação de pré-carregamento em andamento em vez de iniciar uma nova.

A `preload` API também pode ser usada em casos como pré-carregar dados para outra página que provavelmente será renderizada. Mais informações sobre pré-carregamento de dados com SWR podem ser encontradas [aqui](/docs/prefetching).

## `isLoading` [#isloading]

`isLoading` é o novo estado retornado pelo `useSWR`, que indica **se a requisição ainda está em andamento e ainda não há dados carregados**. Anteriormente, o estado `isValidating` representava tanto o estado de carregamento inicial quanto o estado de revalidação, então tínhamos que verificar se tanto `data` quanto `error` eram `undefined` para determinar se era o estado de carregamento inicial.

Agora, é tão fácil que você pode usar o valor `isLoading` diretamente para renderizar uma mensagem de carregamento:

```jsx
import useSWR from 'swr'

function Profile() {
  const { data, isLoading } = useSWR('/api/user', fetcher)

  if (isLoading) return <div>carregando...</div>
  return <div>olá {data.name}!</div>
}
```

Note que `isValidating` ainda está presente, então você ainda pode usá-lo para mostrar um indicador de carregamento para revalidações.

<Callout emoji="📝">
  Nós adicionamos a nova página [Entendendo SWR](/docs/advanced/understanding) para descrever como o SWR retorna valores, que inclui a diferença entre `isValidating` e `isLoading`, e como combiná-los para melhorar a experiência do usuário.
</Callout>

## Preservando o Estado Anterior [#preserving-previous-state]

A opção `keepPreviousData` é uma nova adição que permite manter os dados que foram buscados anteriormente. Isso melhora a UX imensamente quando você está buscando dados com base em ações do usuário acontecendo em tempo real, como com um recurso de pesquisa ao vivo, onde a `key` do recurso continua mudando:

```jsx {5}
function Search() {
  const [search, setSearch] = React.useState('');

  const { data, isLoading } = useSWR(`/search?q=${search}`, fetcher, {
    keepPreviousData: true
  })

  return (
    <div>
      <input
        type="text"
        value={search}
        onChange={(e) => setSearch(e.target.value)}
        placeholder="Pesquisar..."
      />

      <div className={isLoading ? "loading" : ""}>
        {data?.products.map(item => <Product key={item.id} name={item.name} />)
      </div>
    </div>
  );
}
```

<Video
  src="https://user-images.githubusercontent.com/3676859/163695903-a3eb1259-180e-41e0-821e-21c320201194.mp4"
  caption="Preserve os resultados de pesquisa anteriores quando keepPreviousData estiver habilitado"
  ratio={640/730}
/>


Dê uma olhada no código no [CodeSandbox](https://codesandbox.io/s/swr-keeppreviousdata-fsjz3m) e você pode ler mais sobre isso [aqui](/docs/advanced/understanding#retorne-dados-antigos-para-melhorar-a-ux).

## Extendendo Configurações [#extending-configurations]

O `SWRConfig` agora pode aceitar uma função como valor. Quando você tem vários níveis de `<SWRConfig>`, o interno recebe a configuração do pai e retorna uma nova. Essa mudança torna mais flexível configurar o SWR em uma codebase grande. Mais informações podem ser encontradas [aqui](/docs/global-configuration).

```jsx
<SWRConfig
  value={parentConfig => ({
    dedupingInterval: parentConfig.dedupingInterval * 5,
    refreshInterval: 100,
  })}
>
  <Page />
</SWRConfig>
```

## Suporte Melhorado ao React 18 [#improved-react-18-support]

SWR has updated its internal code to use `useSyncExternalStore` and `startTransition` APIs in React 18. These ensure stronger consistency when rendering UI concurrently. This change doesn’t require any user code changes and all developers will benefit from it directly. Shims are included for React 17 and below.

O SWR atualizou seu código interno para usar o `useSyncExternalStore` e as `startTransition` APIs no React 18. Isso garante uma consistência mais forte ao renderizar a UI concorrentemente. Essa mudança não requer nenhuma alteração no código do usuário e todos os desenvolvedores se beneficiarão diretamente. Shims são incluídos para o React 17 e abaixo.

SWR 2.0 e todas as novas funcionalidades ainda são compatíveis com o React 16 e 17.

## Guia de Migração [#migration-guide]

### Fetcher não recebe mais múltiplos argumentos [#fetcher-no-longer-accepts-multiple-arguments]

`key` agora é passado como um argumento único.

```diff
- useSWR([1, 2, 3], (a, b, c) => {
+ useSWR([1, 2, 3], ([a, b, c]) => {
  assert(a === 1)
  assert(b === 2)
  assert(c === 3)
})
```

### Mutação Global não recebe mais uma função `getKey` [#global-mutate-no-longer-accepts-a-getkey-function]

Agora, se você passar uma função para o `mutate` global, ela será usada como um [filtro](/blog/swr-v2##modificando-múltiplos-items). Anteriormente, você podia passar uma função que retornasse uma chave para o `mutate` global:

```diff
- mutate(() => '/api/item') // uma função para retornar a chave
+ mutate('/api/item')       // para modificar a chave, passe-a diretamente
```

### Nova propriedade obrigatória `keys()` para a interface Cache [#new-required-property-keys-for-cache-interface]

Quando você usar sua própria implementação de cache, a interface Cache agora requer um método `keys()` que retorna todas as chaves no objeto cache, similar às instâncias Map do JavaScript.

```diff
interface Cache<Data> {
  get(key: string): Data | undefined
  set(key: string, value: Data): void
  delete(key: string): void
+ keys(): IterableIterator<string>
}
```

### Estrutura interna do Cache alterada [#changed-cache-internal-structure]

A estrutura interna dos dados do cache será um objeto que contém todos os estados atuais.

```diff
- assert(cache.get(key) === data)
+ assert(cache.get(key) === { data, error, isValidating })

// getter
- cache.get(key)
+ cache.get(key)?.data

// setter
- cache.set(key, data)
+ cache.set(key, { ...cache.get(key), data })
```

<Callout emoji="🚨" type="error">
  Você não deveria escrever no cache diretamente, isso pode causar comportamento indefinido.
</Callout>

### `SWRConfig.default` Foi Renomeado para `SWRConfig.defaultValue` [#swrconfigdefault-is-renamed-as-swrconfigdefaultvalue]

O `SWRConfig.defaultValue` é a propriedade para acessar a configuração padrão do SWR.

```diff
- SWRConfig.default
+ SWRConfig.defaultValue
```

### O tipo `InfiniteFetcher` foi renomeado para `SWRInfiniteFetcher` [#type-infinitefetcher-is-renamed-as-swrinfinitefetcher]

```diff
- import type { InfiniteFetcher } from 'swr/infinite'
+ import type { SWRInfiniteFetcher } from 'swr/infinite'
```

### Evitando Suspense no Servidor [#avoid-suspense-on-server]

Se você quer usar `suspense: true` com o SWR no lado do servidor, incluindo pré-renderização no Next.js, então você deve fornecer dados iniciais via [`fallbackData` ou `fallback`](/docs/with-nextjs#pré-renderizando-com-dados-padrão).

Hoje, isso significa que você não pode usar Suspense para buscar dados no lado do servidor. Suas outras duas opções são fazer a busca de dados totalmente no lado do cliente ou obter seu framework para buscar os dados para você (como getStaticProps faz no Next.js).

### ES2018 como alvo de compilação [#es2018-as-the-build-target]

Se você quiser dar suporte ao IE 11, você deve definir o ES5 como alvo de compilação em seu framework ou bundler. Essa mudança fez uma melhoria de desempenho no SSR e mantém o tamanho do pacote pequeno.

## Changelog [#changelog]

Leia o Changelog completo [no GitHub](https://github.com/vercel/swr/releases).

## O futuro e Obrigado! [#the-future--thank-you]

Com o novo lançamento do [Next.js 13](https://nextjs.org/blog/next-13), vemos muitas coisas novas e emocionantes, além de mudanças de paradigma no ecossistema React: [React Server Components](https://beta.nextjs.org/docs/rendering/server-and-client-components), streaming SSR, [async components](https://beta.nextjs.org/docs/data-fetching/fetching#asyncawait-in-server-components), e o [hook `use`](https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md#usepromise). Muitos deles estão relacionados ao data-fetching, e alguns deles têm casos de uso semelhantes com o SWR.

No entanto, o objetivo do projeto SWR permanece o mesmo. Queremos que seja uma biblioteca drop-in que seja leve, agnóstica de framework e um pouco _opinativa_ (por exemplo, revalidar ao foco). Em vez de tentar ser uma solução padrão, queremos nos concentrar em inovações que melhorem a UX. Enquanto isso, também estamos fazendo pesquisas sobre como melhorar o SWR com essas novas capacidades do React.

Queremos agradecer a cada um dos [143](https://github.com/vercel/swr/graphs/contributors) contribuidores (+ [106](https://github.com/vercel/swr-site/graphs/contributors) contribuidores de documentação), bem como aqueles que nos ajudam ou nos dão feedback. Um agradecimento especial vai para [Toru Kobayashi](https://twitter.com/koba04) por todo o seu trabalho nos DevTools e na documentação - não teríamos conseguido sem você!